Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 21, 2026

Description

Adds regression test for custom attribute decoding with generic enum arguments involving arrays. This test validates the fix for a Mono runtime crash caused by incorrect MonoClass resolution for MONO_TYPE_GENERICINST when loading custom attribute values (see #123439).

Note: This PR contains only the regression test. The actual Mono runtime fix is in PR #123439. This PR is meant to land after #123439 to provide test coverage.

Changes Made

Test Addition (System.Reflection.Tests/CustomAttributeTests.cs):

  • Added CustomAttributeCtor_WithGenericEnumArgument_DecodesCorrectly test method
  • Verifies custom attribute with constructor parameter GenericClassForEnum<int[]>.E decodes successfully
  • Ensures no crash when accessing CustomAttributes and ConstructorArguments on decorated types
  • Validates ArgumentType matches the expected generic enum type typeof(GenericClassForEnum<int[]>.E)
  • Validates Value equals the default enum value using Convert.ToInt32() to properly compare the boxed enum value
  • Provides regression coverage for the MONO_TYPE_GENERICINST handling issue
  • Includes [ActiveIssue] attribute for a related bug in System.Reflection.Metadata/NativeAOT (CustomAttribute.DecodeValue doesn't handle generic type instantiations #123878)
private class GenericEnumAttributeWithArray : Attribute
{
    public GenericEnumAttributeWithArray(GenericClassForEnum<int[]>.E e) { }
}

private class GenericClassForEnum<T>
{
    public enum E { }
}

[GenericEnumAttributeWithArray(default)]
private class ClassWithGenericEnumAttribute { }

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/123878", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))]
public void CustomAttributeCtor_WithGenericEnumArgument_DecodesCorrectly()
{
    // This test ensures correct reflection behavior when loading a custom attribute
    // whose constructor argument is a generic enum instance involving an array.
    // This scenario was causing a crash in Mono (see https://github.com/dotnet/runtime/pull/123439)
    var attr = typeof(ClassWithGenericEnumAttribute).CustomAttributes.Single(d => d.AttributeType == typeof(GenericEnumAttributeWithArray));
    var arg = attr.ConstructorArguments.Single();

    // Verify that we can successfully decode the attribute without crashing
    Assert.Equal(typeof(CustomAttributeTypedArgument), arg.GetType());

    // Verify the argument type is the expected generic enum type
    Assert.Equal(typeof(GenericClassForEnum<int[]>.E), arg.ArgumentType);

    // Verify the value is the default enum value (0)
    Assert.Equal(0, Convert.ToInt32(arg.Value));
}

This test provides regression coverage for the issue, ensuring the crash doesn't reoccur after the fix in PR #123439 is merged.

Original prompt

This adds a test to System.Reflection.Tests/CustomAttributeTests.cs that covers loading a custom attribute whose constructor argument is a generic enum instance involving a function pointer array, as in the Mono crash reported in #123439. This ensures correct reflection behavior without crashing or incorrect MonoClass resolution for MONO_TYPE_GENERICINST.

The test, CustomAttributeCtor_WithGenericEnumArgument_DecodesCorrectly, uses the code example from the PR description as scenario coverage.

The new test method is placed inside the CustomAttributeTests class to match repository convention.

This pull request was created from Copilot chat.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Add test for custom attribute with generic enum constructor Add test for custom attribute with generic enum function pointer array argument Jan 21, 2026
Copilot AI requested a review from lewing January 21, 2026 20:55
@lewing
Copy link
Member

lewing commented Jan 21, 2026

@copilot merge #123439 into this pr to verify the fix

Copy link
Contributor Author

Copilot AI commented Jan 21, 2026

@copilot merge #123439 into this pr to verify the fix

Merged the Mono fix from PR #123439 in commit 5542a1f. The test now covers both the regression scenario and validates the fix works correctly.

Copilot AI changed the title Add test for custom attribute with generic enum function pointer array argument Add test and Mono fix for custom attribute with generic enum function pointer array argument Jan 21, 2026
@lewing
Copy link
Member

lewing commented Jan 31, 2026

this is meant to land after #123439 as a test for the mono crash.

@lewing lewing marked this pull request as ready for review January 31, 2026 00:08
@lewing lewing requested a review from thaystg as a code owner January 31, 2026 00:08
Copilot AI review requested due to automatic review settings January 31, 2026 00:08
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds both a Mono runtime fix and a regression test for a crash that occurred when loading custom attributes with generic enum constructor arguments involving function pointer arrays.

Changes:

  • Fixed Mono runtime crash in custom attribute decoding for generic enum types with function pointer arrays
  • Added regression test to prevent future occurrences of this issue

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/mono/mono/metadata/custom-attrs.c Defers tklass initialization for MONO_TYPE_GENERICINST types and updates assertion to handle generic instance cases, preventing crash during custom attribute value loading
src/libraries/System.Runtime/tests/System.Reflection.Tests/CustomAttributeTests.cs Adds CustomAttributeCtor_WithGenericEnumArgument_DecodesCorrectly test to verify custom attributes with generic enum arguments involving function pointer arrays decode without crashing

Comment on lines 306 to 313
var arg = attr.ConstructorArguments.Single();
Assert.Equal(typeof(CustomAttributeTypedArgument), arg.GetType());
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding more comprehensive assertions to validate the actual argument value and type, similar to the BoxedEnumAttributes() test pattern on lines 259-277. For example, you could assert that arg.ArgumentType equals the expected generic enum type typeof(GenericClassForEnum<delegate*<void>[]>.E) and verify the value is the default enum value (0). This would provide stronger regression coverage beyond just ensuring the code doesn't crash.

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply this feedback

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enhanced the test assertions in commit c7189a0. The test now validates:

  • ArgumentType matches the expected generic enum type GenericClassForEnum<delegate*<void>[]>.E
  • Value is the default enum value (0)

This provides stronger regression coverage beyond just ensuring the code doesn't crash.

@MichalStrehovsky
Copy link
Member

@copilot this doesn't build because of src/libraries/System.Runtime/tests/System.Reflection.Tests/CustomAttributeTests.cs(319,47): error CS0214: (NETCORE_ENGINEERING_TELEMETRY=Build) Pointers and fixed size buffers may only be used in an unsafe context

Copy link
Contributor Author

Copilot AI commented Feb 2, 2026

@copilot this doesn't build because of `src/libraries/System.Runtime/tests/System.Reflection.Tests/CustomAttributeTests.cs(319,47): error CS0214: (NETCORE_ENGINEERING_TELEMETRY=Build) Pointers and fix...

Fixed in commit d05fc87. Marked the test method as unsafe to allow the function pointer type usage in the assertions.

@MichalStrehovsky
Copy link
Member

@copilot test failure:

      Assert.Equal() Failure: Values differ
      Expected: 0
      Actual:   0
      Stack Trace:
        /_/src/libraries/System.Runtime/tests/System.Reflection.Tests/CustomAttributeTests.cs(319,0): at System.Reflection.Tests.CustomAttributeTests.CustomAttributeCtor_WithGenericEnumArgument_DecodesCorrectly()

Copy link
Contributor Author

Copilot AI commented Feb 2, 2026

@copilot test failure:

...

Fixed in commit db2bfe7. The issue was comparing a boxed enum value directly with a cast enum type. Changed to use Convert.ToInt32(arg.Value) to compare the underlying integer value instead.

@lewing
Copy link
Member

lewing commented Feb 2, 2026

I'm guessing the mono failures are #90308 now

@MichalStrehovsky
Copy link
Member

I'm guessing the mono failures are #90308 now

Do we need a function pointer array for this regression test? Wouldn't we hit the problem with something like

public unsafe GenericEnumAttributeWithFunctionPointer(GenericClassForEnum<int[]>.E e) { }

too? It would be enough to hit the System.Reflection.Metadata bug. Function pointers might hit more bonus bugs too, but I'd cross that bridge when we get there.

Add regression test for Mono crash when decoding custom attributes
with generic enum arguments involving arrays (PR #123439).

Uses GenericClassForEnum<int[]>.E to test the MONO_TYPE_GENERICINST
handling in custom attribute decoding.

Co-authored-by: Michal Strehovsky <MichalStrehovsky@users.noreply.github.com>
@lewing lewing force-pushed the copilot/add-custom-attribute-test branch from 52f4a3f to a33c5e6 Compare February 3, 2026 19:10
@lewing lewing changed the title Add test and Mono fix for custom attribute with generic enum function pointer array argument Add test for custom attribute with generic enum array argument Feb 3, 2026
@lewing
Copy link
Member

lewing commented Feb 3, 2026

@copilot update the description to reflect the current state of the pr

Copy link
Contributor Author

Copilot AI commented Feb 3, 2026

@copilot update the description to reflect the current state of the pr

Updated the PR description. The current PR now only contains the regression test (not the Mono runtime fix, which is in PR #123439). The test was also simplified to use GenericClassForEnum<int[]>.E instead of function pointer arrays, making it cleaner and no longer requiring unsafe context.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants